package com.xuecheng.publish.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.api.content.model.dto.CourseBaseDTO;
import com.xuecheng.api.content.model.dto.TeachplanDTO;
import com.xuecheng.api.system.model.dto.CourseCategoryDTO;
import com.xuecheng.common.domain.response.RestResponse;
import com.xuecheng.common.enums.content.CourseAuditEnum;
import com.xuecheng.common.enums.content.CourseModeEnum;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.common.util.JsonUtil;
import com.xuecheng.content.common.constant.ContentErrorCode;
import com.xuecheng.content.common.constant.CoursePubTemplateKey;
import com.xuecheng.content.convert.CourseBaseConvert;
import com.xuecheng.content.entity.CourseMarket;
import com.xuecheng.content.entity.CourseTeacher;
import com.xuecheng.content.entity.Teachplan;

import com.xuecheng.publish.common.constant.CoursePublishErrorCode;
import com.xuecheng.publish.common.util.QiniuUtils;
import com.xuecheng.publish.entity.CoursePub;
import com.xuecheng.publish.entity.CoursePubMsg;
import com.xuecheng.publish.mapper.CoursePubMapper;
import com.xuecheng.publish.service.CoursePubService;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 课程发布 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class CoursePubServiceImpl extends ServiceImpl<CoursePubMapper, CoursePub> implements CoursePubService {
    @Autowired
    private Configuration configuration;



    /*
    #生成静态化页面发布位置
    course.publish.position = pages/
    #七牛云的存储消息
    file.qiniu.accessKey = pFcOu02W6CdSqjY6qmRH1jz--pwfQEVyuM4RkBGC
    file.qiniu.secretKey = z4CqmQb9LYD3AiuViX3ADk3r3-iOAm9yQePGP6Hh
    file.qiniu.bucket = xc134-staitc-pages
        * */
    @Value("${file.qiniu.accessKey}")
    private String accessKey;
    @Value("${file.qiniu.secretKey}")
    private String secretKey;
    @Value("${file.qiniu.bucket}")
    private String bucket;
    @Value("${course.publish.position}")
    private String position;


    /**
     *  业务分析：
     *    0. 判断消息是否已被消费  （消息幂等性）  coursePub中的isPub（0:发布  1: 发布）
     *    1. 生成课程页面
     *      1.1 生成数据模型
     *      1.2 生成模板
     *      1.3 生成html
     *      1.4 上传到cdn
     *
     *
     *
     *
     *
     * @param coursePubMsg
     */
    @Override
    public void publishPage(CoursePubMsg coursePubMsg) {
        LambdaQueryWrapper<CoursePub> coursePubLambdaQueryWrapper = new LambdaQueryWrapper<>();
        coursePubLambdaQueryWrapper.eq(CoursePub::getId,coursePubMsg.getPubId());
        coursePubLambdaQueryWrapper.eq(CoursePub::getIsPub, CoursePub.IS_PUB);
        int count = this.count(coursePubLambdaQueryWrapper);

        if(count>0){
            log.info("课程已发布，无需操作该课程，课程id：{}",coursePubMsg.getPubId());
         return;
        }

        // 生成课程页面
        //数据模型  模板
        CoursePub coursePub = null;
        String htmlString = null;
        try {
            coursePub = this.getById(coursePubMsg.getPubId());
            Map<String, Object> dataMap = generateDataMap(coursePub);
            Template template = configuration.getTemplate("learing_article.ftl");
            htmlString = FreeMarkerTemplateUtils.processTemplateIntoString(template, dataMap);
        } catch (Exception e) {
            log.error(CoursePublishErrorCode.E_120209.getDesc()+" coursePubId:{}",coursePub.getId());
            ExceptionCast.cast(CoursePublishErrorCode.E_120209);

        }

        // 修改判别幂等性的标识
//        update set is_pub=0  set changeTime=?where Id=?
        LambdaUpdateWrapper<CoursePub> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(CoursePub::getIsPub,CoursePub.IS_PUB);
        updateWrapper.set(CoursePub::getChangeDate, LocalDateTime.now());
        updateWrapper.eq(CoursePub::getId,coursePubMsg.getPubId());
        boolean update = this.update(updateWrapper);
        if (!update) {
            log.error("课程发布修改发布的状态失败: coursePubId --{}",coursePub.getId());
            // 程序抛出异常，让spring-retry 进行消息的重试
            ExceptionCast.cast(CoursePublishErrorCode.E_120207);
        }
        // 3.上传cdn
        try {
            String htmlkey=position+coursePubMsg.getPubId()+".html";
            QiniuUtils.upload2Qiniu(accessKey,secretKey,bucket,htmlString,htmlkey);
        } catch (Exception e) {
            log.error(CoursePublishErrorCode.E_120210.getDesc()+" coursePubId:{}",coursePub.getId());
            ExceptionCast.cast(CoursePublishErrorCode.E_120210);
        }


    }

    private Map<String, Object> generateDataMap(CoursePub coursePub) {

        Map<String ,Object> map =new HashMap<>();

        map.put(CoursePubTemplateKey.COURSEPUB,coursePub);

        map.put(CoursePubTemplateKey.COURSEMARKET,JsonUtil.jsonToObject(coursePub.getMarket(), CourseMarket.class));

        CourseModeEnum[] values = CourseModeEnum.values();

        map.put(CoursePubTemplateKey.TEACHPLANNODE,JsonUtil.jsonToObject(coursePub.getTeachplan(), Teachplan.class));

//        String value = coursePub.getTeachmode();

        map.put(CoursePubTemplateKey.COURSETEACHMODEENUMS,values);

        // 课程教师

        String teachersJsonString = coursePub.getTeachers();

        List<CourseTeacher> teachers = JsonUtil.jsonToList(teachersJsonString, CourseTeacher.class);

        map.put("Teachers",teachers);


        return map;
    }
}
